package com.ruoyi.common.core.utils.pay;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.DefaultSigner;
import com.alipay.api.Signer;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.ruoyi.common.core.utils.uuid.Seq;
import com.ruoyi.common.core.web.domain.AjaxResult;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 支付宝接口对接
 */
public class AlipayPayUtil {


	/**
	 * @Description: 如何使用java发送http请求，调用第三方接口
	 * @Param: [orderNum, price, title]
	 * @Return: java.lang.String
	 * @Author: luqian
	 * @Date: 2024/6/26 3:29 PM
	 */
	public static String alipayPayMy(String orderNum, BigDecimal price, String title){
		//1.要调用第三方，就要知道第三方的接口4要素
		//1.1.请求地址 ：https://openapi-sandbox.dl.alipaydev.com/gateway.do
		//1.2.请求方式 : post
		//1.3.请求参数和请求头 : 看官方文档
		Map<String, Object> params = new TreeMap<>();
		params.put("app_id", AlipayConfig.appId);
		params.put("method", "alipay.trade.page.pay");
		params.put("format", "json");
		params.put("charset", AlipayConfig.input_charset_utf);
		params.put("sign_type", AlipayConfig.sign_type_rsa2);
		params.put("timestamp", DateUtil.formatDateTime(DateUtil.date()));
		params.put("version", "1.0");

        Map<String, Object> businessParameters = new HashMap<>();

		businessParameters.put("out_trade_no","10000020");
		businessParameters.put("total_amount","0.01");
		businessParameters.put("subject","测试订单");
		businessParameters.put("product_code","FAST_INSTANT_TRADE_PAY");
		params.put("biz_content", JSONObject.toJSONString(businessParameters));



		String sourceContent = HttpUtil.toParams(params);
		Signer defaultSigner = new DefaultSigner(AlipayConfig.privateKey);
		String decode = URLDecoder.decode(sourceContent, Charset.forName("UTF-8"));
		String sign = defaultSigner.sign(decode,AlipayConfig.sign_type_rsa2, AlipayConfig.input_charset_utf);
		params.put("sign",sign);


		//公共参数和业务参数合并
		params.putAll(businessParameters);

		String post = HttpUtil.post(AlipayConfig.alipayGateway, params);

		//1.4 响应参数：看官方文档
		return  post;

	}

	/**
	 * 发起支付请求
	 * 统一收单下单并支付页面接口
	 *
	 * @return
	 */
	public static AjaxResult alipayPay(String orderNum, BigDecimal price, String title){
		try{
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId,  AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf,  AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2);
			AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
			//异步接收地址，仅支持http/https，公网可访问
			request.setNotifyUrl(AlipayConfig.notifyUrl);
			//同步跳转地址，仅支持http/https
			request.setReturnUrl(AlipayConfig.returnUrl);
			/******必传参数******/
			JSONObject bizContent = new JSONObject();
			//商户订单号，商家自定义，保持唯一性
			bizContent.put("out_trade_no",orderNum);
			//支付金额，最小值0.01元
			bizContent.put("total_amount",price);
			//订单标题，不可使用特殊符号
			bizContent.put("subject",title);
			//订单描述
			bizContent.put("body", title);
			//电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
			bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

			request.setBizContent(bizContent.toString());

			AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
			if (response.isSuccess()) {
				return AjaxResult.success(response.getBody());
			} else {
				return AjaxResult.error("调用失败");
			}
		}catch (Exception e){
			e.printStackTrace();
			return AjaxResult.error("调用失败");
		}

	}

	/**
	 * 统一收单线下交易查询接口
	 * @param tradeNo  支付宝交易号
	 */
	public AjaxResult alipayQuery(String tradeNo){
       try{
		   AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId,  AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf,  AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2);
		   AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		   JSONObject bizContent = new JSONObject();
		   bizContent.put("trade_no", tradeNo);
		   request.setBizContent(bizContent.toString());
		   AlipayTradeQueryResponse response = alipayClient.execute(request);
		   if(response.isSuccess()){
			   return AjaxResult.success(response.getBody());
		   } else {
			   return AjaxResult.error("调用失败");
		   }
	   }catch (Exception e){
		   e.printStackTrace();
		   return AjaxResult.error("调用失败");
	   }
	}

	/**
	 * 统一收单交易关闭接口
	 * @param tradeNo 支付宝交易号
	 */
	public AjaxResult alipayClose(String tradeNo){
       try{
		   AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId,  AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf,  AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2);
		   AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
		   JSONObject bizContent = new JSONObject();
		   bizContent.put("trade_no", tradeNo);
		   request.setBizContent(bizContent.toString());
		   AlipayTradeCloseResponse response = alipayClient.execute(request);
		   if(response.isSuccess()){
			   return AjaxResult.success(response.getBody());
		   } else {
			   return AjaxResult.error("调用失败");
		   }
	   }catch (Exception e){
		   e.printStackTrace();
		   return AjaxResult.error("调用失败");
	   }
	}

	/**
	 * 统一收单交易退款请求
	 *  全额退款，out_request_no 选填。
	 * 	部分退款，out_request_no 必传。
	 * @param tradeNo 支付宝交易号
	 */
	public AjaxResult alipayRefund(String tradeNo,BigDecimal price){
		try{
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId,  AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf,  AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2);
			AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
			JSONObject bizContent = new JSONObject();
			bizContent.put("trade_no", tradeNo);
			bizContent.put("refund_amount", price);
			bizContent.put("out_request_no", "T"+ Seq.getId());
			request.setBizContent(bizContent.toString());
			AlipayTradeRefundResponse response = alipayClient.execute(request);
			if(response.isSuccess()){
				return AjaxResult.success(response.getBody());
			} else {
				return AjaxResult.error("调用失败");
			}
		}catch (Exception e){
			e.printStackTrace();
			return AjaxResult.error("调用失败");
		}
	}

	/**
	 * 统一收单交易退款查询
	 * @param tradeNo 支付宝交易号
	 */
	public AjaxResult alipayRefundQuery(String tradeNo){
		try{
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId,  AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf,  AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2);
			AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
			JSONObject bizContent = new JSONObject();
			bizContent.put("trade_no", tradeNo);
			bizContent.put("out_request_no","T"+ Seq.getId());
			request.setBizContent(bizContent.toString());
			AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
			if(response.isSuccess()){
				return AjaxResult.success(response.getBody());
			} else {
				return AjaxResult.error("调用失败");
			}
		}catch (Exception e){
			e.printStackTrace();
			return AjaxResult.error("调用失败");
		}
	}

}
